์๋ฐ์คํฌ๋ฆฝํธ ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ ํ์ดํ๋ผ์ธ์ผ๋ก ํจ์จ์ ์ธ ๋ฐ์ดํฐ ์ฒ๋ฆฌ๋ฅผ ๊ฒฝํํ์ธ์. ์ด ๊ฐ์ด๋๋ ํ์ฅ ๊ฐ๋ฅํ๊ณ ๋ฐ์์ฑ์ด ๋ฐ์ด๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ํ ๊ฐ๋ ฅํ ์คํธ๋ฆผ ์ฒ๋ฆฌ ์ฒด์ธ ๊ตฌ์ถ ๋ฐฉ๋ฒ์ ๋ค๋ฃน๋๋ค.
์๋ฐ์คํฌ๋ฆฝํธ ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ ํ์ดํ๋ผ์ธ: ์คํธ๋ฆผ ์ฒ๋ฆฌ ์ฒด์ธ
ํ๋ ์๋ฐ์คํฌ๋ฆฝํธ ๊ฐ๋ฐ ์ธ๊ณ์์ ๋์ฉ๋ ๋ฐ์ดํฐ์ ๊ณผ ๋น๋๊ธฐ ์์ ์ ํจ์จ์ ์ผ๋ก ์ฒ๋ฆฌํ๋ ๊ฒ์ ๋งค์ฐ ์ค์ํฉ๋๋ค. ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ์ ํ์ดํ๋ผ์ธ์ ๋ฐ์ดํฐ ์คํธ๋ฆผ์ ๋น๋๊ธฐ์ ์ผ๋ก ์ฒ๋ฆฌํ๊ณ , ๋ ผ๋ธ๋กํน(non-blocking) ๋ฐฉ์์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ๋ณํํ๊ณ ์กฐ์ํ๋ ๊ฐ๋ ฅํ ๋ฉ์ปค๋์ฆ์ ์ ๊ณตํฉ๋๋ค. ์ด ์ ๊ทผ ๋ฐฉ์์ ์ค์๊ฐ ๋ฐ์ดํฐ, ๋์ฉ๋ ํ์ผ ๋๋ ๋ณต์กํ ๋ฐ์ดํฐ ๋ณํ์ ์ฒ๋ฆฌํ๋ ํ์ฅ ๊ฐ๋ฅํ๊ณ ๋ฐ์์ฑ์ด ๋ฐ์ด๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ถํ๋ ๋ฐ ํนํ ์ ์ฉํฉ๋๋ค.
๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ๋ ๋ฌด์์ธ๊ฐ?
๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ๋ ๊ฐ์ ์ํ์ค๋ฅผ ๋น๋๊ธฐ์ ์ผ๋ก ๋ฐ๋ณตํ ์ ์๊ฒ ํด์ฃผ๋ ํ๋ ์๋ฐ์คํฌ๋ฆฝํธ์ ๊ธฐ๋ฅ์ ๋๋ค. ์ผ๋ฐ ์ดํฐ๋ ์ดํฐ์ ์ ์ฌํ์ง๋ง, ๊ฐ์ ์ง์ ๋ฐํํ๋ ๋์ ์ํ์ค์ ๋ค์ ๊ฐ์ผ๋ก ํ์ธ(resolve)๋๋ ํ๋ก๋ฏธ์ค(promise)๋ฅผ ๋ฐํํฉ๋๋ค. ์ด๋ฌํ ๋น๋๊ธฐ์ ํน์ฑ ๋๋ถ์ ๋คํธ์ํฌ ์คํธ๋ฆผ, ํ์ผ ์ฝ๊ธฐ, ์ผ์ ๋ฐ์ดํฐ์ ๊ฐ์ด ์๊ฐ ๊ฒฝ๊ณผ์ ๋ฐ๋ผ ๋ฐ์ดํฐ๋ฅผ ์์ฑํ๋ ๋ฐ์ดํฐ ์์ค๋ฅผ ์ฒ๋ฆฌํ๋ ๋ฐ ์ด์์ ์ ๋๋ค.
๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ๋ ํ๋ก๋ฏธ์ค๋ฅผ ๋ฐํํ๋ next() ๋ฉ์๋๋ฅผ ๊ฐ์ง๋๋ค. ์ด ํ๋ก๋ฏธ์ค๋ ๋ ๊ฐ์ง ์์ฑ์ ๊ฐ์ง ๊ฐ์ฒด๋ก ํ์ธ๋ฉ๋๋ค:
value: ์ํ์ค์ ๋ค์ ๊ฐ์ ๋๋ค.done: ๋ฐ๋ณต์ด ์๋ฃ๋์๋์ง๋ฅผ ๋ํ๋ด๋ ๋ถ๋ฆฌ์ธ(boolean) ๊ฐ์ ๋๋ค.
๋ค์์ ์ซ์ ์ํ์ค๋ฅผ ์์ฑํ๋ ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ์ ๊ฐ๋จํ ์์ ์ ๋๋ค:
async function* numberGenerator(limit) {
for (let i = 0; i < limit; i++) {
await new Promise(resolve => setTimeout(resolve, 100)); // ๋น๋๊ธฐ ์์
์๋ฎฌ๋ ์ด์
yield i;
}
}
(async () => {
for await (const number of numberGenerator(5)) {
console.log(number);
}
})();
์ด ์์ ์์ numberGenerator๋ ๋น๋๊ธฐ ์ ๋๋ ์ดํฐ ํจ์(async function* ๊ตฌ๋ฌธ์ผ๋ก ํ์)์
๋๋ค. ์ด ํจ์๋ 0๋ถํฐ limit - 1๊น์ง์ ์ซ์ ์ํ์ค๋ฅผ ์์ฑ(yield)ํฉ๋๋ค. for await...of ๋ฃจํ๋ ์ ๋๋ ์ดํฐ๊ฐ ์์ฑํ ๊ฐ๋ค์ ๋น๋๊ธฐ์ ์ผ๋ก ๋ฐ๋ณตํฉ๋๋ค.
์ค์ ์๋๋ฆฌ์ค์์ ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ ์ดํดํ๊ธฐ
๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ๋ ๋ค์๊ณผ ๊ฐ์ด ๋ณธ์ง์ ์ผ๋ก ๋๊ธฐ๊ฐ ํ์ํ ์์ ์ ์ฒ๋ฆฌํ ๋ ๋ฐ์ด๋ ์ฑ๋ฅ์ ๋ฐํํฉ๋๋ค:
- ๋์ฉ๋ ํ์ผ ์ฝ๊ธฐ: ์ ์ฒด ํ์ผ์ ๋ฉ๋ชจ๋ฆฌ์ ๋ก๋ํ๋ ๋์ , ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ๋ ํ์ผ์ ์ค ๋จ์ ๋๋ ์ฒญํฌ ๋จ์๋ก ์ฝ์ด ๊ฐ ๋ถ๋ถ์ ์ฌ์ฉํ ์ ์๊ฒ ๋ ๋๋ง๋ค ์ฒ๋ฆฌํ ์ ์์ต๋๋ค. ์ด๋ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋์ ์ต์ํํ๊ณ ๋ฐ์์ฑ์ ํฅ์์ํต๋๋ค. ์๋ฅผ ๋ค์ด, ๋์ฟ์ ์๋ ์๋ฒ์ ๋์ฉ๋ ๋ก๊ทธ ํ์ผ์ ์ฒ๋ฆฌํ๋ค๊ณ ์์ํด ๋ณด์ธ์. ๋คํธ์ํฌ ์ฐ๊ฒฐ์ด ๋๋ฆฌ๋๋ผ๋ ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ๋ฅผ ์ฌ์ฉํ์ฌ ์ฒญํฌ ๋จ์๋ก ์ฝ์ ์ ์์ต๋๋ค.
- API์์ ๋ฐ์ดํฐ ์คํธ๋ฆฌ๋ฐ: ๋ง์ API๊ฐ ์คํธ๋ฆฌ๋ฐ ํ์์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ์ ๊ณตํฉ๋๋ค. ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ๋ ์ด ์คํธ๋ฆผ์ ์๋นํ์ฌ ์ ์ฒด ์๋ต์ด ๋ค์ด๋ก๋๋ ๋๊น์ง ๊ธฐ๋ค๋ฆฌ์ง ์๊ณ ๋ฐ์ดํฐ๊ฐ ๋์ฐฉํ๋ ๋๋ก ์ฒ๋ฆฌํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ์ฃผ๊ฐ๋ฅผ ์คํธ๋ฆฌ๋ฐํ๋ ๊ธ์ต ๋ฐ์ดํฐ API๊ฐ ์์ต๋๋ค.
- ์ค์๊ฐ ์ผ์ ๋ฐ์ดํฐ: IoT ์ฅ์น๋ ์ข ์ข ์ง์์ ์ธ ์ผ์ ๋ฐ์ดํฐ ์คํธ๋ฆผ์ ์์ฑํฉ๋๋ค. ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ๋ฅผ ์ฌ์ฉํ์ฌ ์ด ๋ฐ์ดํฐ๋ฅผ ์ค์๊ฐ์ผ๋ก ์ฒ๋ฆฌํ๊ณ ํน์ ์ด๋ฒคํธ๋ ์๊ณ๊ฐ์ ๋ฐ๋ผ ์์ ์ ํธ๋ฆฌ๊ฑฐํ ์ ์์ต๋๋ค. ์๋ฅดํจํฐ๋์ ๊ธฐ์ ์ผ์๊ฐ ์จ๋ ๋ฐ์ดํฐ๋ฅผ ์คํธ๋ฆฌ๋ฐํ๋ค๊ณ ์๊ฐํด ๋ณด์ธ์. ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ๋ ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ๊ณ ์จ๋๊ฐ ์ํ๋ก ๋จ์ด์ง๋ฉด ๊ฒฝ๊ณ ๋ฅผ ๋ณด๋ผ ์ ์์ต๋๋ค.
๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ ํ์ดํ๋ผ์ธ์ด๋ ๋ฌด์์ธ๊ฐ?
๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ ํ์ดํ๋ผ์ธ์ ๋ฐ์ดํฐ ์คํธ๋ฆผ์ ์ฒ๋ฆฌํ๊ธฐ ์ํด ํจ๊ป ์ฐ๊ฒฐ๋ ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ์ ์ํ์ค์ ๋๋ค. ํ์ดํ๋ผ์ธ์ ๊ฐ ์ดํฐ๋ ์ดํฐ๋ ๋ฐ์ดํฐ๋ฅผ ์ฒด์ธ์ ๋ค์ ์ดํฐ๋ ์ดํฐ๋ก ์ ๋ฌํ๊ธฐ ์ ์ ํน์ ๋ณํ์ด๋ ์์ ์ ์ํํฉ๋๋ค. ์ด๋ฅผ ํตํด ๋ชจ๋์์ด๊ณ ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ ๋ฐฉ์์ผ๋ก ๋ณต์กํ ๋ฐ์ดํฐ ์ฒ๋ฆฌ ์ํฌํ๋ก์ฐ๋ฅผ ๊ตฌ์ถํ ์ ์์ต๋๋ค.
ํต์ฌ ์์ด๋์ด๋ ๋ณต์กํ ์ฒ๋ฆฌ ์์ ์ ๊ฐ๊ฐ ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ๋ก ํํ๋๋ ๋ ์๊ณ ๊ด๋ฆฌํ๊ธฐ ์ฌ์ด ๋จ๊ณ๋ก ๋๋๋ ๊ฒ์ ๋๋ค. ๊ทธ๋ฐ ๋ค์ ์ด ์ดํฐ๋ ์ดํฐ๋ค์ ํ์ดํ๋ผ์ธ์ผ๋ก ์ฐ๊ฒฐ๋๋ฉฐ, ํ ์ดํฐ๋ ์ดํฐ์ ์ถ๋ ฅ์ด ๋ค์ ์ดํฐ๋ ์ดํฐ์ ์ ๋ ฅ์ด ๋ฉ๋๋ค.
์กฐ๋ฆฝ ๋ผ์ธ์ ์๊ฐํด๋ณด์ธ์. ๊ฐ ์คํ ์ด์ ์ ๋ผ์ธ์ ๋ฐ๋ผ ์ด๋ํ๋ ์ ํ์ ๋ํด ํน์ ์์ ์ ์ํํฉ๋๋ค. ์ฐ๋ฆฌ์ ๊ฒฝ์ฐ, ์ ํ์ ๋ฐ์ดํฐ ์คํธ๋ฆผ์ด๊ณ ์คํ ์ด์ ์ ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ์ ๋๋ค.
๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ ํ์ดํ๋ผ์ธ ๊ตฌ์ถํ๊ธฐ
๋ค์๊ณผ ๊ฐ์ ์์ ์ ์ํํ๋ ๊ฐ๋จํ ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ ํ์ดํ๋ผ์ธ ์์ ๋ฅผ ๋ง๋ค์ด ๋ณด๊ฒ ์ต๋๋ค:
- ์ซ์ ์ํ์ค๋ฅผ ์์ฑํฉ๋๋ค.
- ํ์๋ฅผ ๊ฑธ๋ฌ๋ ๋๋ค.
- ๋จ์ ์ง์๋ฅผ ์ ๊ณฑํฉ๋๋ค.
- ์ ๊ณฑ๋ ์ซ์๋ฅผ ๋ฌธ์์ด๋ก ๋ณํํฉ๋๋ค.
async function* numberGenerator(limit) {
for (let i = 0; i < limit; i++) {
yield i;
}
}
async function* filter(source, predicate) {
for await (const item of source) {
if (predicate(item)) {
yield item;
}
}
}
async function* map(source, transform) {
for await (const item of source) {
yield transform(item);
}
}
(async () => {
const numbers = numberGenerator(10);
const evenNumbers = filter(numbers, (number) => number % 2 === 0);
const squaredNumbers = map(evenNumbers, (number) => number * number);
const stringifiedNumbers = map(squaredNumbers, (number) => number.toString());
for await (const numberString of stringifiedNumbers) {
console.log(numberString);
}
})();
์ด ์์ ์์:
numberGenerator๋ 0๋ถํฐ 9๊น์ง์ ์ซ์ ์ํ์ค๋ฅผ ์์ฑํฉ๋๋ค.filter๋ ํ์๋ฅผ ๊ฑธ๋ฌ๋ด๊ณ ์ง์๋ง ๋จ๊น๋๋ค.map์ ๊ฐ ์ง์๋ฅผ ์ ๊ณฑํฉ๋๋ค.map์ ๊ฐ ์ ๊ณฑ๋ ์ซ์๋ฅผ ๋ฌธ์์ด๋ก ๋ณํํฉ๋๋ค.
for await...of ๋ฃจํ๋ ํ์ดํ๋ผ์ธ์ ๋ง์ง๋ง ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ(stringifiedNumbers)๋ฅผ ๋ฐ๋ณตํ๋ฉฐ, ๊ฐ ์ ๊ณฑ๋ ์ซ์๋ฅผ ๋ฌธ์์ด๋ก ์ฝ์์ ์ถ๋ ฅํฉ๋๋ค.
๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ ํ์ดํ๋ผ์ธ ์ฌ์ฉ์ ์ฃผ์ ์ด์
๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ ํ์ดํ๋ผ์ธ์ ๋ค์๊ณผ ๊ฐ์ ๋ช ๊ฐ์ง ์ค์ํ ์ด์ ์ ์ ๊ณตํฉ๋๋ค:
- ์ฑ๋ฅ ํฅ์: ๋ฐ์ดํฐ๋ฅผ ๋น๋๊ธฐ์ ์ผ๋ก ๊ทธ๋ฆฌ๊ณ ์ฒญํฌ ๋จ์๋ก ์ฒ๋ฆฌํจ์ผ๋ก์จ, ํนํ ๋์ฉ๋ ๋ฐ์ดํฐ์ ์ด๋ ๋๋ฆฐ ๋ฐ์ดํฐ ์์ค๋ฅผ ๋ค๋ฃฐ ๋ ํ์ดํ๋ผ์ธ์ ์ฑ๋ฅ์ ํฌ๊ฒ ํฅ์์ํฌ ์ ์์ต๋๋ค. ์ด๋ ๋ฉ์ธ ์ค๋ ๋๋ฅผ ์ฐจ๋จํ๋ ๊ฒ์ ๋ฐฉ์งํ๊ณ ๋ ๋ฐ์์ฑ์ด ์ข์ ์ฌ์ฉ์ ๊ฒฝํ์ ๋ณด์ฅํฉ๋๋ค.
- ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋ ๊ฐ์: ํ์ดํ๋ผ์ธ์ ์คํธ๋ฆฌ๋ฐ ๋ฐฉ์์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ๋ฏ๋ก ์ ์ฒด ๋ฐ์ดํฐ์ ์ ํ ๋ฒ์ ๋ฉ๋ชจ๋ฆฌ์ ๋ก๋ํ ํ์๊ฐ ์์ต๋๋ค. ์ด๋ ๋งค์ฐ ํฐ ํ์ผ์ด๋ ์ฐ์์ ์ธ ๋ฐ์ดํฐ ์คํธ๋ฆผ์ ์ฒ๋ฆฌํ๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋งค์ฐ ์ค์ํฉ๋๋ค.
- ๋ชจ๋์ฑ ๋ฐ ์ฌ์ฌ์ฉ์ฑ: ํ์ดํ๋ผ์ธ์ ๊ฐ ์ดํฐ๋ ์ดํฐ๋ ํน์ ์์ ์ ์ํํ๋ฏ๋ก ์ฝ๋๊ฐ ๋ ๋ชจ๋ํ๋๊ณ ์ดํดํ๊ธฐ ์ฌ์์ง๋๋ค. ์ดํฐ๋ ์ดํฐ๋ ๋ค๋ฅธ ๋ฐ์ดํฐ ์คํธ๋ฆผ์ ๋ํด ๋์ผํ ๋ณํ์ ์ํํ๊ธฐ ์ํด ๋ค๋ฅธ ํ์ดํ๋ผ์ธ์์ ์ฌ์ฌ์ฉ๋ ์ ์์ต๋๋ค.
- ๊ฐ๋ ์ฑ ์ฆ๊ฐ: ํ์ดํ๋ผ์ธ์ ๋ณต์กํ ๋ฐ์ดํฐ ์ฒ๋ฆฌ ์ํฌํ๋ก์ฐ๋ฅผ ๋ช ํํ๊ณ ๊ฐ๊ฒฐํ๊ฒ ํํํ์ฌ ์ฝ๋๋ฅผ ์ฝ๊ณ ์ ์ง ๊ด๋ฆฌํ๊ธฐ ์ฝ๊ฒ ๋ง๋ญ๋๋ค. ํจ์ํ ํ๋ก๊ทธ๋๋ฐ ์คํ์ผ์ ๋ถ๋ณ์ฑ์ ์ด์งํ๊ณ ๋ถ์์ฉ์ ํผํ์ฌ ์ฝ๋ ํ์ง์ ๋์ฑ ํฅ์์ํต๋๋ค.
- ์ค๋ฅ ์ฒ๋ฆฌ: ํ์ดํ๋ผ์ธ์์ ๊ฒฌ๊ณ ํ ์ค๋ฅ ์ฒ๋ฆฌ๋ฅผ ๊ตฌํํ๋ ๊ฒ์ ๋งค์ฐ ์ค์ํฉ๋๋ค. ๊ฐ ๋จ๊ณ๋ฅผ try/catch ๋ธ๋ก์ผ๋ก ๊ฐ์ธ๊ฑฐ๋ ์ฒด์ธ์ ์ ์ฉ ์ค๋ฅ ์ฒ๋ฆฌ ์ดํฐ๋ ์ดํฐ๋ฅผ ํ์ฉํ์ฌ ์ ์ฌ์ ์ธ ๋ฌธ์ ๋ฅผ ์ฐ์ํ๊ฒ ๊ด๋ฆฌํ ์ ์์ต๋๋ค.
๊ณ ๊ธ ํ์ดํ๋ผ์ธ ๊ธฐ๋ฒ
์์ ๊ธฐ๋ณธ ์์ ๋ฅผ ๋์ด์, ๋ ์ ๊ตํ ๊ธฐ๋ฒ์ ์ฌ์ฉํ์ฌ ๋ณต์กํ ํ์ดํ๋ผ์ธ์ ๊ตฌ์ถํ ์ ์์ต๋๋ค:
- ๋ฒํผ๋ง(Buffering): ๋๋ก๋ ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ๊ธฐ ์ ์ ์ผ์ ๋์ ๋ฐ์ดํฐ๋ฅผ ์ถ์ ํด์ผ ํ ํ์๊ฐ ์์ต๋๋ค. ํน์ ์๊ณ๊ฐ์ ๋๋ฌํ ๋๊น์ง ๋ฐ์ดํฐ๋ฅผ ๋ฒํผ๋งํ ๋ค์, ๋ฒํผ๋ง๋ ๋ฐ์ดํฐ๋ฅผ ๋จ์ผ ์ฒญํฌ๋ก ๋ด๋ณด๋ด๋ ์ดํฐ๋ ์ดํฐ๋ฅผ ๋ง๋ค ์ ์์ต๋๋ค. ์ด๋ ์ผ๊ด ์ฒ๋ฆฌ๋ ๊ฐ๋ณ ์๋๋ฅผ ๊ฐ์ง ๋ฐ์ดํฐ ์คํธ๋ฆผ์ ํํํํ๋ ๋ฐ ์ ์ฉํ ์ ์์ต๋๋ค.
- ๋๋ฐ์ด์ฑ(Debouncing) ๋ฐ ์ค๋กํ๋ง(Throttling): ์ด๋ฌํ ๊ธฐ๋ฒ์ ๋ฐ์ดํฐ ์ฒ๋ฆฌ ์๋๋ฅผ ์ ์ดํ์ฌ ๊ณผ๋ถํ๋ฅผ ๋ฐฉ์งํ๊ณ ์ฑ๋ฅ์ ํฅ์์ํค๋ ๋ฐ ์ฌ์ฉ๋ ์ ์์ต๋๋ค. ๋๋ฐ์ด์ฑ์ ๋ง์ง๋ง ๋ฐ์ดํฐ ํญ๋ชฉ์ด ๋์ฐฉํ ํ ์ผ์ ์๊ฐ์ด ์ง๋ ๋๊น์ง ์ฒ๋ฆฌ๋ฅผ ์ง์ฐ์ํต๋๋ค. ์ค๋กํ๋ง์ ์ฒ๋ฆฌ ์๋๋ฅผ ๋จ์ ์๊ฐ๋น ์ต๋ ํญ๋ชฉ ์๋ก ์ ํํฉ๋๋ค.
- ์ค๋ฅ ์ฒ๋ฆฌ: ๊ฒฌ๊ณ ํ ์ค๋ฅ ์ฒ๋ฆฌ๋ ๋ชจ๋ ํ์ดํ๋ผ์ธ์ ํ์์ ์ ๋๋ค. ๊ฐ ์ดํฐ๋ ์ดํฐ ๋ด์์ try/catch ๋ธ๋ก์ ์ฌ์ฉํ์ฌ ์ค๋ฅ๋ฅผ ์ก๊ณ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค. ๋๋ ์ค๋ฅ๋ฅผ ๊ฐ๋ก์ฑ๊ณ ์ค๋ฅ ๋ก๊น ์ด๋ ์์ ์ฌ์๋์ ๊ฐ์ ์ ์ ํ ์กฐ์น๋ฅผ ์ํํ๋ ์ ์ฉ ์ค๋ฅ ์ฒ๋ฆฌ ์ดํฐ๋ ์ดํฐ๋ฅผ ๋ง๋ค ์ ์์ต๋๋ค.
- ๋ฐฑํ๋ ์ (Backpressure): ๋ฐฑํ๋ ์ ๊ด๋ฆฌ๋ ํ์ดํ๋ผ์ธ์ด ๋ฐ์ดํฐ์ ์๋๋นํ์ง ์๋๋ก ํ๋ ๋ฐ ๋งค์ฐ ์ค์ํฉ๋๋ค. ๋ค์ด์คํธ๋ฆผ ์ดํฐ๋ ์ดํฐ๊ฐ ์ ์คํธ๋ฆผ ์ดํฐ๋ ์ดํฐ๋ณด๋ค ๋๋ฆฐ ๊ฒฝ์ฐ, ์ ์คํธ๋ฆผ ์ดํฐ๋ ์ดํฐ๋ ๋ฐ์ดํฐ ์์ฑ ์๋๋ฅผ ๋ฆ์ถฐ์ผ ํ ์ ์์ต๋๋ค. ์ด๋ ํ๋ฆ ์ ์ด(flow control)๋ ๋ฐ์ํ ํ๋ก๊ทธ๋๋ฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๊ฐ์ ๊ธฐ๋ฒ์ ์ฌ์ฉํ์ฌ ๋ฌ์ฑํ ์ ์์ต๋๋ค.
๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ ํ์ดํ๋ผ์ธ์ ์ค์ ์์
์ค์ ์๋๋ฆฌ์ค์์ ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ ํ์ดํ๋ผ์ธ์ด ์ด๋ป๊ฒ ์ฌ์ฉ๋ ์ ์๋์ง ๋ช ๊ฐ์ง ๋ ์ค์ฉ์ ์ธ ์์ ๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค:
์์ 1: ๋์ฉ๋ CSV ํ์ผ ์ฒ๋ฆฌํ๊ธฐ
์ฒ๋ฆฌํด์ผ ํ ๊ณ ๊ฐ ๋ฐ์ดํฐ๊ฐ ํฌํจ๋ ๋์ฉ๋ CSV ํ์ผ์ด ์๋ค๊ณ ์์ํด ๋ณด์ธ์. ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ ํ์ดํ๋ผ์ธ์ ์ฌ์ฉํ์ฌ ํ์ผ์ ์ฝ๊ณ , ๊ฐ ์ค์ ํ์ฑํ๊ณ , ๋ฐ์ดํฐ ์ ํจ์ฑ ๊ฒ์ฌ ๋ฐ ๋ณํ์ ์ํํ ์ ์์ต๋๋ค.
const fs = require('fs');
const readline = require('readline');
async function* readFileLines(filePath) {
const fileStream = fs.createReadStream(filePath);
const rl = readline.createInterface({
input: fileStream,
crlfDelay: Infinity
});
for await (const line of rl) {
yield line;
}
}
async function* parseCSV(source) {
for await (const line of source) {
const values = line.split(',');
// ์ฌ๊ธฐ์ ๋ฐ์ดํฐ ์ ํจ์ฑ ๊ฒ์ฌ ๋ฐ ๋ณํ ์ํ
yield values;
}
}
(async () => {
const filePath = 'path/to/your/customer_data.csv';
const lines = readFileLines(filePath);
const parsedData = parseCSV(lines);
for await (const row of parsedData) {
console.log(row);
}
})();
์ด ์์ ๋ readline์ ์ฌ์ฉํ์ฌ CSV ํ์ผ์ ์ค ๋จ์๋ก ์ฝ์ ๋ค์ ๊ฐ ์ค์ ๊ฐ์ ๋ฐฐ์ด๋ก ํ์ฑํฉ๋๋ค. ํ์ดํ๋ผ์ธ์ ๋ ๋ง์ ์ดํฐ๋ ์ดํฐ๋ฅผ ์ถ๊ฐํ์ฌ ์ถ๊ฐ์ ์ธ ๋ฐ์ดํฐ ์ ํจ์ฑ ๊ฒ์ฌ, ์ ๋ฆฌ ๋ฐ ๋ณํ์ ์ํํ ์ ์์ต๋๋ค.
์์ 2: ์คํธ๋ฆฌ๋ฐ API ์ฌ์ฉํ๊ธฐ
๋ง์ API๊ฐ ์๋ฒ-์ ์ก ์ด๋ฒคํธ(SSE)๋ ์น์์ผ๊ณผ ๊ฐ์ ์คํธ๋ฆฌ๋ฐ ํ์์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ์ ๊ณตํฉ๋๋ค. ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ ํ์ดํ๋ผ์ธ์ ์ฌ์ฉํ์ฌ ์ด๋ฌํ ์คํธ๋ฆผ์ ์๋นํ๊ณ ์ค์๊ฐ์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค.
const fetch = require('node-fetch');
async function* fetchStream(url) {
const response = await fetch(url);
const reader = response.body.getReader();
try {
while (true) {
const { done, value } = await reader.read();
if (done) {
return;
}
yield new TextDecoder().decode(value);
}
} finally {
reader.releaseLock();
}
}
async function* processData(source) {
for await (const chunk of source) {
// ์ฌ๊ธฐ์ ๋ฐ์ดํฐ ์ฒญํฌ ์ฒ๋ฆฌ
yield chunk;
}
}
(async () => {
const url = 'https://api.example.com/data/stream';
const stream = fetchStream(url);
const processedData = processData(stream);
for await (const data of processedData) {
console.log(data);
}
})();
์ด ์์ ๋ fetch API๋ฅผ ์ฌ์ฉํ์ฌ ์คํธ๋ฆฌ๋ฐ ์๋ต์ ๊ฒ์ํ ๋ค์ ์๋ต ๋ณธ๋ฌธ์ ์ฒญํฌ ๋จ์๋ก ์ฝ์ต๋๋ค. ํ์ดํ๋ผ์ธ์ ๋ ๋ง์ ์ดํฐ๋ ์ดํฐ๋ฅผ ์ถ๊ฐํ์ฌ ๋ฐ์ดํฐ๋ฅผ ํ์ฑํ๊ณ ๋ณํํ๋ฉฐ ๋ค๋ฅธ ์์
์ ์ํํ ์ ์์ต๋๋ค.
์์ 3: ์ค์๊ฐ ์ผ์ ๋ฐ์ดํฐ ์ฒ๋ฆฌํ๊ธฐ
์์ ์ธ๊ธํ๋ฏ์ด, ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ ํ์ดํ๋ผ์ธ์ IoT ์ฅ์น์ ์ค์๊ฐ ์ผ์ ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ๋ ๋ฐ ์ ํฉํฉ๋๋ค. ํ์ดํ๋ผ์ธ์ ์ฌ์ฉํ์ฌ ๋ฐ์ดํฐ๊ฐ ๋์ฐฉํ๋ ๋๋ก ํํฐ๋ง, ์ง๊ณ ๋ฐ ๋ถ์ํ ์ ์์ต๋๋ค.
// ์ผ์ ๋ฐ์ดํฐ๋ฅผ ๋น๋๊ธฐ ์ดํฐ๋ฌ๋ธ๋ก ๋ฐฉ์ถํ๋ ํจ์๊ฐ ์๋ค๊ณ ๊ฐ์
async function* sensorDataStream() {
// ์ผ์ ๋ฐ์ดํฐ ๋ฐฉ์ถ ์๋ฎฌ๋ ์ด์
while (true) {
await new Promise(resolve => setTimeout(resolve, 500));
yield Math.random() * 100; // ์จ๋ ์ธก์ ๊ฐ ์๋ฎฌ๋ ์ด์
}
}
async function* filterOutliers(source, threshold) {
for await (const reading of source) {
if (reading > threshold) {
yield reading;
}
}
}
async function* calculateAverage(source, windowSize) {
let buffer = [];
for await (const reading of source) {
buffer.push(reading);
if (buffer.length > windowSize) {
buffer.shift();
}
if (buffer.length === windowSize) {
const average = buffer.reduce((sum, val) => sum + val, 0) / windowSize;
yield average;
}
}
}
(async () => {
const sensorData = sensorDataStream();
const filteredData = filterOutliers(sensorData, 90); // 90 ์ด๊ณผ ์ธก์ ๊ฐ ํํฐ๋ง
const averageTemperature = calculateAverage(filteredData, 5); // 5๊ฐ ์ธก์ ๊ฐ์ ๋ํ ํ๊ท ๊ณ์ฐ
for await (const average of averageTemperature) {
console.log(`Average Temperature: ${average.toFixed(2)}`);
}
})();
์ด ์์ ๋ ์ผ์ ๋ฐ์ดํฐ ์คํธ๋ฆผ์ ์๋ฎฌ๋ ์ด์ ํ ๋ค์ ํ์ดํ๋ผ์ธ์ ์ฌ์ฉํ์ฌ ์ด์์น ์ธก์ ๊ฐ์ ํํฐ๋งํ๊ณ ์ด๋ ํ๊ท ์จ๋๋ฅผ ๊ณ์ฐํฉ๋๋ค. ์ด๋ฅผ ํตํด ์ผ์ ๋ฐ์ดํฐ์ ์ถ์ธ์ ์ด์ ์งํ๋ฅผ ์๋ณํ ์ ์์ต๋๋ค.
๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ ํ์ดํ๋ผ์ธ์ ์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋ฐ ๋๊ตฌ
์ผ๋ฐ ์๋ฐ์คํฌ๋ฆฝํธ๋ฅผ ์ฌ์ฉํ์ฌ ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ ํ์ดํ๋ผ์ธ์ ๊ตฌ์ถํ ์๋ ์์ง๋ง, ํ๋ก์ธ์ค๋ฅผ ๋จ์ํํ๊ณ ์ถ๊ฐ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ ์ฌ๋ฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋๊ตฌ๊ฐ ์์ต๋๋ค:
- IxJS (Reactive Extensions for JavaScript): IxJS๋ ์๋ฐ์คํฌ๋ฆฝํธ์์ ๋ฐ์ํ ํ๋ก๊ทธ๋๋ฐ์ ์ํ ๊ฐ๋ ฅํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋๋ค. ๋น๋๊ธฐ ์ดํฐ๋ฌ๋ธ์ ์์ฑํ๊ณ ์กฐ์ํ๊ธฐ ์ํ ํ๋ถํ ์ฐ์ฐ์ ์ธํธ๋ฅผ ์ ๊ณตํ์ฌ ๋ณต์กํ ํ์ดํ๋ผ์ธ์ ์ฝ๊ฒ ๊ตฌ์ถํ ์ ์์ต๋๋ค.
- Highland.js: Highland.js๋ ์๋ฐ์คํฌ๋ฆฝํธ๋ฅผ ์ํ ํจ์ํ ์คํธ๋ฆฌ๋ฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋๋ค. IxJS์ ์ ์ฌํ ์ฐ์ฐ์ ์ธํธ๋ฅผ ์ ๊ณตํ์ง๋ง ๋จ์์ฑ๊ณผ ์ฌ์ฉ ํธ์์ฑ์ ์ค์ ์ ๋ก๋๋ค.
- Node.js Streams API: Node.js๋ ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ๋ฅผ ๋ง๋๋ ๋ฐ ์ฌ์ฉํ ์ ์๋ ๋ด์ฅ Streams API๋ฅผ ์ ๊ณตํฉ๋๋ค. Streams API๋ IxJS๋ Highland.js๋ณด๋ค ์ ์์ค์ด์ง๋ง ์คํธ๋ฆฌ๋ฐ ํ๋ก์ธ์ค์ ๋ํ ๋ ๋ง์ ์ ์ด๊ถ์ ์ ๊ณตํฉ๋๋ค.
์ผ๋ฐ์ ์ธ ํจ์ ๊ณผ ๋ชจ๋ฒ ์ฌ๋ก
๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ ํ์ดํ๋ผ์ธ์ ๋ง์ ์ด์ ์ ์ ๊ณตํ์ง๋ง, ํ์ดํ๋ผ์ธ์ด ๊ฒฌ๊ณ ํ๊ณ ํจ์จ์ ์ธ์ง ํ์ธํ๊ธฐ ์ํด ๋ช ๊ฐ์ง ์ผ๋ฐ์ ์ธ ํจ์ ์ ์ธ์ํ๊ณ ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ๋ฐ๋ฅด๋ ๊ฒ์ด ์ค์ํฉ๋๋ค:
- ๋ธ๋กํน ์์ ํผํ๊ธฐ: ํ์ดํ๋ผ์ธ์ ๋ชจ๋ ์ดํฐ๋ ์ดํฐ๊ฐ ๋ฉ์ธ ์ค๋ ๋๋ฅผ ์ฐจ๋จํ์ง ์๋๋ก ๋น๋๊ธฐ ์์ ์ ์ํํ๋์ง ํ์ธํ์ธ์. ๋น๋๊ธฐ ํจ์์ ํ๋ก๋ฏธ์ค๋ฅผ ์ฌ์ฉํ์ฌ I/O ๋ฐ ๊ธฐํ ์๊ฐ์ด ๋ง์ด ๊ฑธ๋ฆฌ๋ ์์ ์ ์ฒ๋ฆฌํ์ธ์.
- ์ฐ์ํ๊ฒ ์ค๋ฅ ์ฒ๋ฆฌํ๊ธฐ: ๊ฐ ์ดํฐ๋ ์ดํฐ์ ๊ฒฌ๊ณ ํ ์ค๋ฅ ์ฒ๋ฆฌ๋ฅผ ๊ตฌํํ์ฌ ์ ์ฌ์ ์ธ ์ค๋ฅ๋ฅผ ์ก๊ณ ์ฒ๋ฆฌํ์ธ์. try/catch ๋ธ๋ก์ด๋ ์ ์ฉ ์ค๋ฅ ์ฒ๋ฆฌ ์ดํฐ๋ ์ดํฐ๋ฅผ ์ฌ์ฉํ์ฌ ์ค๋ฅ๋ฅผ ๊ด๋ฆฌํ์ธ์.
- ๋ฐฑํ๋ ์ ๊ด๋ฆฌํ๊ธฐ: ํ์ดํ๋ผ์ธ์ด ๋ฐ์ดํฐ์ ์๋๋นํ๋ ๊ฒ์ ๋ฐฉ์งํ๊ธฐ ์ํด ๋ฐฑํ๋ ์ ๊ด๋ฆฌ๋ฅผ ๊ตฌํํ์ธ์. ํ๋ฆ ์ ์ด๋ ๋ฐ์ํ ํ๋ก๊ทธ๋๋ฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๊ฐ์ ๊ธฐ๋ฒ์ ์ฌ์ฉํ์ฌ ๋ฐ์ดํฐ ํ๋ฆ์ ์ ์ดํ์ธ์.
- ์ฑ๋ฅ ์ต์ ํํ๊ธฐ: ํ์ดํ๋ผ์ธ์ ํ๋กํ์ผ๋งํ์ฌ ์ฑ๋ฅ ๋ณ๋ชฉ ํ์์ ์๋ณํ๊ณ ๊ทธ์ ๋ฐ๋ผ ์ฝ๋๋ฅผ ์ต์ ํํ์ธ์. ๋ฒํผ๋ง, ๋๋ฐ์ด์ฑ, ์ค๋กํ๋ง๊ณผ ๊ฐ์ ๊ธฐ๋ฒ์ ์ฌ์ฉํ์ฌ ์ฑ๋ฅ์ ํฅ์์ํค์ธ์.
- ์ฒ ์ ํ๊ฒ ํ ์คํธํ๊ธฐ: ํ์ดํ๋ผ์ธ์ด ๋ค๋ฅธ ์กฐ๊ฑด์์๋ ์ฌ๋ฐ๋ฅด๊ฒ ์๋ํ๋์ง ์ฒ ์ ํ๊ฒ ํ ์คํธํ์ธ์. ๋จ์ ํ ์คํธ์ ํตํฉ ํ ์คํธ๋ฅผ ์ฌ์ฉํ์ฌ ๊ฐ ์ดํฐ๋ ์ดํฐ์ ์ ์ฒด ํ์ดํ๋ผ์ธ์ ๋์์ ๊ฒ์ฆํ์ธ์.
๊ฒฐ๋ก
๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ ํ์ดํ๋ผ์ธ์ ๋์ฉ๋ ๋ฐ์ดํฐ์ ๊ณผ ๋น๋๊ธฐ ์์ ์ ์ฒ๋ฆฌํ๋ ํ์ฅ ๊ฐ๋ฅํ๊ณ ๋ฐ์์ฑ์ด ๋ฐ์ด๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ถํ๊ธฐ ์ํ ๊ฐ๋ ฅํ ๋๊ตฌ์ ๋๋ค. ๋ณต์กํ ๋ฐ์ดํฐ ์ฒ๋ฆฌ ์ํฌํ๋ก์ฐ๋ฅผ ๋ ์๊ณ ๊ด๋ฆฌํ๊ธฐ ์ฌ์ด ๋จ๊ณ๋ก ๋๋์ผ๋ก์จ ํ์ดํ๋ผ์ธ์ ์ฑ๋ฅ์ ํฅ์์ํค๊ณ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋์ ์ค์ด๋ฉฐ ์ฝ๋ ๊ฐ๋ ์ฑ์ ๋์ผ ์ ์์ต๋๋ค. ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ์ ํ์ดํ๋ผ์ธ์ ๊ธฐ๋ณธ์ ์ดํดํ๊ณ ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ๋ฐ๋ฅด๋ฉด ์ด ๊ธฐ์ ์ ํ์ฉํ์ฌ ํจ์จ์ ์ด๊ณ ๊ฒฌ๊ณ ํ ๋ฐ์ดํฐ ์ฒ๋ฆฌ ์๋ฃจ์ ์ ๊ตฌ์ถํ ์ ์์ต๋๋ค.
๋น๋๊ธฐ ํ๋ก๊ทธ๋๋ฐ์ ํ๋ ์๋ฐ์คํฌ๋ฆฝํธ ๊ฐ๋ฐ์์ ํ์์ ์ด๋ฉฐ, ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ์ ํ์ดํ๋ผ์ธ์ ๋ฐ์ดํฐ ์คํธ๋ฆผ์ ์ฒ๋ฆฌํ๋ ๊นจ๋ํ๊ณ ํจ์จ์ ์ด๋ฉฐ ๊ฐ๋ ฅํ ๋ฐฉ๋ฒ์ ์ ๊ณตํฉ๋๋ค. ๋์ฉ๋ ํ์ผ์ ์ฒ๋ฆฌํ๋ , ์คํธ๋ฆฌ๋ฐ API๋ฅผ ์ฌ์ฉํ๋ , ์ค์๊ฐ ์ผ์ ๋ฐ์ดํฐ๋ฅผ ๋ถ์ํ๋ , ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ ํ์ดํ๋ผ์ธ์ ์ค๋๋ ์ ๋ฐ์ดํฐ ์ง์ฝ์ ์ธ ์ธ๊ณ์ ์๊ตฌ๋ฅผ ์ถฉ์กฑํ๋ ํ์ฅ ๊ฐ๋ฅํ๊ณ ๋ฐ์์ฑ์ด ๋ฐ์ด๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ถํ๋ ๋ฐ ๋์์ด ๋ ์ ์์ต๋๋ค.